#include "../inc/skyBuffer.h"
#define  IsStaticBuffer(str)	(0 != (const_cast<Buffer*>(str)->_size & 0x80000000))
#define  toStaticBuffer(len)	(len |= 0x80000000)
namespace Sky
{
Sky::Buffer::Buffer( staticBuffer& buff )
{
    _len  = buff._len;
    _size = buff._size;
    _buff = buff._buff;
    _head = buff._buff;
    toStaticBuffer(_size);
}

Sky::Buffer::Buffer( dynamicBuffer& buff )
{
    _len =  buff._len;
    _size = buff._size;
    _buff = buff._buff;
    _head = buff._buff;
    _buff = (u8*)Memory::alloc(_size);
    Memory::copy(_buff,buff._buff,_size);
}

Sky::Buffer::Buffer( managedBuffer& buff )
{
    _len  = buff._len;
    _size = buff._size;
    _buff = buff._buff;
    _head = buff._buff;
}

Sky::Buffer::Buffer( const Buffer& buf )
{
	if(buf.isExactKindOf(Buffer::Class))
	{
		{//dynamic string
			_size = buf._size;
			_len = buf._len;
			_head = buf._head;
			if(!IsStaticBuffer((&buf)))
			{
				_buff = (u8*)Memory::alloc(_size);
				Memory::copy(_buff,buf._buff,_size);
			}
			else
			{
				_buff = buf._buff;
				toStaticBuffer(_size);
			}
		}
		return;
	}
	return;
}

Sky::Buffer::Buffer( i32 size )
{
	managedBuffer buff(size);
	_len  = buff._len;
	_size = buff._size;
	_buff = buff._buff;
	_head = buff._buff;
}

Sky::Buffer::Buffer( u8* buff,int size ) :_buff(buff),_head(_buff),_len(0),_size(size)
{
	toStaticBuffer(_size);
}

Sky::Void Sky::Buffer::clear()
{
    if(!(IsStaticBuffer(this))&&_buff)
    {
        Memory::free(_buff);
        _buff = vNull;
        _len = 0;
        _size = 0;
        _head = vNull;
    }
}

Sky::Buffer::~Buffer()
{
    clear();
}
}